//
// Created by void on 24-1-20.
//
#include "TcpConnection.h"
#include "Log.h"
TcpConnection::TcpConnection(int fd, EventLoop* evLoop) {
    m_evLoop = evLoop;
    m_readBuf = new Buffer(10240);
    m_writeBuf = new Buffer(10240);

    m_request = new HttpRequest;
    m_response = new HttpResponse;

    m_name = "Connection-"+ to_string(fd);
    m_channel = new Channel(fd, FDEvent::ReadEvent,processRead,
                            processWrite, destroy, this);
    evLoop->addTask(m_channel, ElemType::ADD);
}

TcpConnection::~TcpConnection() {
    if(m_readBuf && m_readBuf->readablesize() == 0 &&
       m_writeBuf && m_writeBuf->readablesize() == 0) {
        delete m_readBuf;
        delete m_writeBuf;
        delete m_request;
        delete m_response;
        m_evLoop->freeChannel(m_channel);
    }
    Debug("连接断开, 释放资源, gameover, connName: %s", m_name.data());
}

int TcpConnection::processRead(void *arg) {
    TcpConnection* conn = static_cast<TcpConnection*>(arg);

    int socket = conn->m_channel->getSocket();
    int count = conn->m_readBuf->socketRead(socket);

    Debug("recv request:%s", conn->m_readBuf->data());
    std::cout << conn->m_readBuf->data() << endl;

    if(count > 0) {
        conn->m_channel->writeEventEnable(true);
        conn->m_evLoop->addTask(conn->m_channel, ElemType::MODIFY);

        bool flag = conn->m_request->parseHttpRequest(conn->m_readBuf,
                                                      conn->m_response,
                                                      conn->m_writeBuf,
                                                      socket);
        if(!flag) {
            string errMsg = "Http/1.1 400 Bad Request\r\n\r\n";
            conn->m_writeBuf->appendString(errMsg);
        }
    } else {
        conn->m_evLoop->addTask(conn->m_channel, ElemType::DELETE);
    }

    conn->m_evLoop->addTask(conn->m_channel, ElemType::DELETE);

    return 0;
}

int TcpConnection::processWrite(void *arg) {
    TcpConnection* conn = static_cast<TcpConnection*>(arg);

    int count = conn->m_writeBuf->sendData(conn->m_channel->getSocket());
    if(count > 0) {
        if(conn->m_writeBuf->readablesize() == 0) {
            conn->m_channel->writeEventEnable(false);

            conn->m_evLoop->addTask(conn->m_channel, ElemType::MODIFY);

            conn->m_evLoop->addTask(conn->m_channel, ElemType::DELETE);
        }
    }
    return 0;
}

int TcpConnection::destroy(void *arg) {
    TcpConnection* conn = static_cast<TcpConnection*> (arg);
    if(conn != nullptr) {
        delete conn;
    }
    return 0;
}
